package com.gaff.emp.core.modules.perm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gaff.emp.core.EmpException;
import com.gaff.emp.core.PageR;
import com.gaff.emp.core.modules.perm.MenuUtil;
import com.gaff.emp.core.modules.perm.controller.role.form.CreateForm;
import com.gaff.emp.core.modules.perm.controller.role.form.UpdateForm;
import com.gaff.emp.core.modules.perm.dao.SysRoleDao;
import com.gaff.emp.core.modules.perm.dao.SysRoleMenuDao;
import com.gaff.emp.core.modules.perm.dao.SysUserDao;
import com.gaff.emp.core.modules.perm.entity.SysMenu;
import com.gaff.emp.core.modules.perm.entity.SysRole;
import com.gaff.emp.core.modules.perm.entity.SysRoleMenu;
import com.gaff.emp.core.modules.perm.entity.SysUser;
import com.gaff.emp.core.modules.perm.service.SysMenuService;
import com.gaff.emp.core.modules.perm.service.SysRoleService;
import com.gaff.emp.core.modules.perm.service.SysUserService;
import com.gaff.emp.core.util.PageQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;


@Service
public class SysRoleServiceImpl implements SysRoleService {

    @Autowired
    private SysRoleDao sysRoleDao;

    @Autowired
    private SysRoleMenuDao sysRoleMenuDao;

    @Autowired
    private SysUserDao sysUserDao;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private SysUserService sysUserService;

    @Override
    public SysRole queryById(Integer roleId) {
        return sysRoleDao.selectById(roleId);
    }

    @Override
    public List<SysMenu> queryMenusByRoleId(int roleId) {
        List<SysMenu> menus = sysRoleDao.queryMenusByRoleId(roleId);
        return MenuUtil.mergeMenus(menus);
    }

    @Override
    public PageR queryRolesByPage(Map<String, Object> params) {
        String roleCode = (String) params.get("roleCode");
        IPage<SysRole> page = sysRoleDao.selectPage(
                PageQuery.<SysRole>getPage(params),
                Wrappers.<SysRole>query()
                        .like(StrUtil.isNotBlank(roleCode), "role_code", roleCode));
        return new PageR(page);
    }

    @Override
    public List<SysRole> queryAllRoles() {
        return sysRoleDao.selectList(Wrappers.emptyWrapper());
    }

    @Override
    @Transactional
    public void createRole(CreateForm form) {
        SysRole role = sysRoleDao.selectOne(Wrappers.<SysRole>query()
                .eq("role_code", form.getRoleCode()));
        if (role != null) {
            throw new EmpException("角色代码重复");
        }
        role = new SysRole();
        BeanUtil.copyProperties(form, role);
        sysRoleDao.insert(role);
        insertRoleMenus(role.getId(), form.getMenuIds());
    }

    @Override
    @Transactional
    public void updateRole(UpdateForm form) {
        SysRole role = sysRoleDao.selectById(form.getId());
        if (role == null) {
            throw new EmpException("角色不存在");
        }
        BeanUtil.copyProperties(form, role);
        sysRoleDao.updateById(role);
        sysUserDao.updateRoleNameByRoleId(role.getId(), role.getRoleName());
        sysRoleMenuDao.delete(Wrappers.<SysRoleMenu>query().eq("role_id", form.getId()));
        insertRoleMenus(role.getId(), form.getMenuIds());
    }

    @Override
    @Transactional
    public void deleteById(Integer id) {
        SysRole role = sysRoleDao.selectById(id);
        if (role == null) {
            return;
        }
        List<SysUser> users = sysUserService.queryByRoleId(id);
        if (users != null && users.size() > 0) {
            throw new EmpException("角色下存在用户，不能删除");
        }
        sysRoleDao.deleteById(id);
        sysRoleMenuDao.delete(Wrappers.<SysRoleMenu>query().eq("role_id", id));
    }

    private void insertRoleMenus(Integer roleId, List<Integer> menuIds) {
        if (menuIds == null) {
            return;
        }
        for (Integer menuId : menuIds) {
            SysMenu menu = sysMenuService.queryMenuById(menuId);
            if (menu == null) {
                continue;
            }
            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setRoleId(roleId);
            roleMenu.setMenuId(menuId);
            sysRoleMenuDao.insert(roleMenu);
        }
    }
}
